In conventional operating systems, each file is allocated a fixed number of blocks of disk space for storing file data as well as control information about the file. The blocks are fixed-sized so that the blocks may be quickly allocated and deallocated. The control information for the files and the file data are often variable-sized, which poses at least two problems. First, when the control information and/or file data is not large enough to fill a block, disk space within the block is wasted. Second, when the control information and/or file data is too large to be stored in a single block, it must be stored in multiple blocks and multiple pointers are maintained to specify where the data is stored. Maintaining and using such pointers is often quite cumbersome.